<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <script>
    // 多层对象或者数组如何深拷贝 ？
    function deepCopy (obj1) {
      var obj2 = Object.prototype.toString.call(obj1) === "[object Array]" ? [] : {};
      for (var key in obj1) {
        if (obj1.hasOwnProperty(key)) {
          if (typeof obj1[key] === "object") {
            // 分成2种情况处理 1.简单数据 直接赋值给新的 obj2  
            // 2.复杂数据类型还要重新生成一个单独地址的数组或者是对象
            // 判断循环出来的属性是否是自身属性 ，不需要处理原型及原型链上的属性和方法  复杂数据类型 数组、对象
            obj2[key] = deepCopy(obj1[key]);
          } else {
            obj2[key] = obj1[key];
          }
        }
      }
      return obj2;
    }

    Object.prototype.height = "178cm"; // 原始的对象上height属性 不需要被拷贝
    var obj1 = {
      name: "张三",
      age: 20,
      hobby: {
        name1: "篮球",
        name2: "足球"
      }
    }

    var obj2 = deepCopy(obj1);
    // console.log(obj2);
    obj2.hobby.name1 = "乒乓球";
    console.log(obj1); // 乒乓球不会有


    // for in 循环对象 特点: 可以循环原型链
    // Object.hasOwnProperty(key) ：可以判断 某个属性是否是对象自身的属性
    // console.log(obj1.hasOwnProperty("height"));

    // for (var key in obj1) {
    //   //   判断循环出来的属性是否是自身属性 ，不需要处理原型及原型链上的属性和方法
    //   if (obj1.hasOwnProperty(key)) {
    //     console.log(key);
    //   }
    // }


     /* 
    一、json ：1.json是什么 ？ 固定格式字符串 主流数据传输格式 json 、xml
    二、json的使用？1.前后端交互（后面讲） 2.深拷贝 缺点 忽略 undefined function map 和set
    三、深拷贝 
      1.引用 ，解决引用问题   深拷贝
      2.新创建一个对象或者是一个数组，开辟一个新的内存空间 ，把要拷贝数据加到新的对象或者数组里
      3.判断数据类型 ？
        3.1 typeof 简单数据类型和函数  
        3.2.instanceof ：判断实例和构造器在原型链上是否有关系 
        3.3 ES5 精确判断数据类型 Object.prototype.toString.call(数据); 
        3.4 constructor可以判断数据类型
      4.深拷贝的深层对象或者是数组问题 ？ 通过递归循环创建新的对象或者是数组
      5.解决for in 循环原型链的问题  对象.hasOwnProperty(键名) 判断某个键名是否是自身属性。
    */


    // constructor可以判断数据类型：某个实例是否是某个构造器构造出来的；
    // function Person(name,age){
    //     this.name = name;
    //     this.age = age;
    // }
    // var zhangsan = new Person("张三",20);
    // if(zhangsan.constructor===Person){
    //     console.log("张三对象是Person构造器构造出来的");
    // }else{
    //     console.log("不是");
    // }


    // var arr = [1,2,3];
    // // var obj = {};
    // // if(obj.constructor===Array){
    // //     console.log("数组");
    // // }else{
    // //     console.log("不是数组");
    // // }

    // console.log(arr.constructor===Array);
    // console.log(arr.constructor===Object);
    // console.log(typeof arr === "object");




  </script>
</body>

</html>